package tmc.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JSplitPane;
import javax.swing.JToolBar;
import javax.swing.UIManager;

import org.apache.log4j.Logger;
import org.geotools.data.FeatureSource;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.map.DefaultMapContext;
import org.geotools.map.MapContext;
import org.geotools.map.MapLayer;
import org.geotools.styling.Style;
import org.geotools.swing.action.InfoAction;
import org.geotools.swing.action.PanAction;
import org.geotools.swing.action.ResetAction;
import org.geotools.swing.action.ZoomInAction;
import org.geotools.swing.action.ZoomOutAction;

import tmc.logic.actionListeners.OpenFileActionListener;
import tmc.logic.actionListeners.SaveFileActionListener;
import tmc.main.LayerObject;
import tmc.main.TMCConstants;

/**
 * main fram
 * 
 * @author Jacek
 * 
 */
public class TMCFrame extends JFrame {

	static Logger LOGGER = Logger.getLogger(TMCFrame.class);

	private JSplitPane mainSplitPane = new JSplitPane();
	
	private JMenuBar menuBar;
	private JToolBar toolBar;
	private TMCStatusBar statusBar;
	
	private TMCFrame mainFrame = this;
	private List<LayerObject> vectorsList = new ArrayList<LayerObject>();
	private MapView mapView;
	private LeftMenuView leftMenuView;
	private MapContext map;
	private TMCFrame tmcFrame = this;

	public TMCFrame() {
		setTitle(TMCConstants.APP_NAME);
		init();
	}

	private void init() {
		LOGGER.debug("Initializing class TMCFrame");
		// setting L&F
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			System.err.println("no such look and feel found");
		}

		map = new DefaultMapContext();

		JMenu menu = new JMenu();
		menu.setText("File");
		JMenuItem item = new JMenuItem("Open");
		item.addActionListener(new OpenFileActionListener(this));
		menu.add(item);
		item = new JMenuItem("Save");
		item.addActionListener(new SaveFileActionListener(this));
		menu.add(item);

		item = new JMenuItem("Exit");

		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				mainFrame.dispose();
				System.exit(NORMAL);
			}
		});
		menu.add(item);
		menuBar = new JMenuBar();
		menuBar.add(menu);
		
		// Help
		menu = new JMenu();
		menu.setText("Help");
		item = new JMenuItem("About");
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(tmcFrame, TMCConstants.APP_NAME
						+ " developed by M.Garski and J.Pawełczak.", "About",
						JOptionPane.INFORMATION_MESSAGE);
			}
		});
		menu.add(item);

		menuBar.add(menu);
		setJMenuBar(menuBar);
	
		// main views
		
		leftMenuView = new LeftMenuView(mainFrame);
		mainSplitPane.setLeftComponent(leftMenuView);
		
		mapView = new MapView(mainFrame);
		
		// status bar
		
		statusBar = new TMCStatusBar(mapView);
		

		// toolbar for map view

		toolBar = new JToolBar();
		toolBar.setOrientation(JToolBar.HORIZONTAL);
		toolBar.setFloatable(false);

		ButtonGroup cursorToolGrp = new ButtonGroup();

		JButton zoomInBtn = new JButton(new ZoomInAction(mapView));
		toolBar.add(zoomInBtn);
		cursorToolGrp.add(zoomInBtn);

		JButton zoomOutBtn = new JButton(new ZoomOutAction(mapView));
		toolBar.add(zoomOutBtn);
		cursorToolGrp.add(zoomOutBtn);

		toolBar.addSeparator();

		JButton panBtn = new JButton(new PanAction(mapView));
		toolBar.add(panBtn);
		cursorToolGrp.add(panBtn);

		toolBar.addSeparator();

		JButton infoBtn = new JButton(new InfoAction(mapView));
		toolBar.add(infoBtn);

		toolBar.addSeparator();

		JButton resetBtn = new JButton(new ResetAction(mapView));
		toolBar.add(resetBtn);

		
		toolBar.setVisible(true);
		
		mapView.add(toolBar);
		
		mainSplitPane.setRightComponent(mapView);
		mainSplitPane
				.setDividerLocation(TMCConstants.LEFT_MENU_VIEW_HORIZONTAL_SIZE);
		
		add(mainSplitPane);
		
		add(statusBar, BorderLayout.SOUTH);
		

		setSize(new Dimension(TMCConstants.LEFT_MENU_VIEW_HORIZONTAL_SIZE
				+ TMCConstants.MAP_VIEW_HORIZONTAL_SIZE,
				TMCConstants.TMC_FRAME_VERTICAL_SIZE + statusBar.getMinimumSize().height));
		
		repaint();
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
	}

	/**
	 * @param vectorsList
	 *            the vectorsList to set
	 */
	public void setVectorsList(List<LayerObject> vectorsList) {
		this.vectorsList = vectorsList;
	}

	/**
	 * @return the vectorsList
	 */
	public List<LayerObject> getVectorsList() {
		return vectorsList;
	}

	/**
	 * @param mapView
	 *            the mapView to set
	 */
	public void setMapView(MapView mapView) {
		this.mapView = mapView;
	}

	/**
	 * @return the mapView
	 */
	public MapView getMapView() {
		return mapView;
	}

	/**
	 * @param leftMenuView
	 *            the leftMenuView to set
	 */
	public void setLeftMenuView(LeftMenuView leftMenuView) {
		this.leftMenuView = leftMenuView;
	}

	/**
	 * @return the leftMenuView
	 */
	public LeftMenuView getLeftMenuView() {
		return leftMenuView;
	}

	/**
	 * @param map
	 *            the map to set
	 */
	public void setMap(MapContext map) {
		this.map = map;
	}

	/**
	 * @return the map
	 */
	public MapContext getMap() {
		return map;
	}

	public void addLayer(FeatureSource featureSource, Style style, String title) {

		LOGGER.debug("adding new layer: " + title);
		MapLayer mapLayer = new MapLayer(featureSource, style, title);

		getLeftMenuView().add(
				new LayerControlPanel(getLeftMenuView(), getMapView(),
						mapLayer, map));
		
		if (getMapView().getMapContext() == null) {
			getMapView().setMapContext(map);
		}
		
		getMapView().reset();
	}
}
